package co.fitstart.admin.web.controller.user.student;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.demo2do.core.support.Page;
import com.demo2do.core.support.Result;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.web.resolver.Preloading;
import com.demo2do.core.web.utils.WebUtils;
import co.fitstart.admin.entity.report.BodyReport;
import co.fitstart.admin.entity.search.OfflineStudentSearch;
import co.fitstart.admin.entity.search.OnlineStudentSearch;
import co.fitstart.admin.entity.security.Login;
import co.fitstart.admin.service.CourseRoundService;
import co.fitstart.admin.service.DataService;
import co.fitstart.admin.service.PrincipalService;
import co.fitstart.admin.service.SiteService;
import co.fitstart.admin.service.SmsBlackListService;
import co.fitstart.admin.service.StudentService;
import co.fitstart.admin.web.interceptor.MenuSetting;
import co.fitstart.admin.web.resolver.Secure;
import co.fitstart.admin.web.view.ExcelTemplateView;
import co.fitstart.entity.course.CourseType;
import co.fitstart.entity.course.round.CourseRound;
import co.fitstart.entity.course.schedule.CourseSchedule;
import co.fitstart.entity.principal.Principal;
import co.fitstart.entity.site.Site;
import co.fitstart.entity.user.Student;
import co.fitstart.entity.user.User;

/**
 * 
 * @author hanDa
 *
 */
@Controller
@RequestMapping("")
@MenuSetting("menu-user")
public class StudentController {
    
    @Autowired
    private StudentService studentService;
    
    @Autowired
    private CourseRoundService courseRoundService;
    
    @Autowired
    @Qualifier("dataService")
    private DataService<User> userService;
    
    @Autowired
    private SiteService siteService;
    
    @Autowired
    private PrincipalService principalService;
    
    @Autowired
    private  SmsBlackListService smsBlackListService;
    
    private static final Logger logger = LoggerFactory.getLogger(StudentController.class);
    
    /**
     * List student by page & type
     * 
     * @param type
     * @param page
     * @param request
     * @return
     */
    @RequestMapping(value = "/{type}-students", method = RequestMethod.GET)
    @MenuSetting("submenu-{type}-student-management")
    public ModelAndView list(@Secure Login login,
                             @PathVariable(value = "type") String type,
                             @RequestParam(name = "site", required = false) Long siteId,
                             Page page,
                             HttpServletRequest request) {
        
        ModelAndView modelAndView = new ModelAndView("student/student-list");
        
        List<Student> students = new ArrayList<Student>();
        
        Site site = null;
        if((login.hasSite() || (siteId != null && siteId != 0)) && StringUtils.equals(type, "offline")) {
            if(login.hasSite()) {
                site = login.getSite();
            }
            else {
                site = siteService.load(siteId);
            }
            students = studentService.list(site, page);
        } else if(StringUtils.equals(type, "offline") && (login.isAreaManager() || login.isAreaServer())) {
            Principal principal = principalService.load(Principal.class, login.getId());
            
            List<Site> sites = siteService.listSite(principal);
            
            if(!sites.isEmpty()) {
                students = studentService.list(sites, page);
            }
        } else {
            students = studentService.list(type, page);
        }
        
        modelAndView.addObject("type", type);
        modelAndView.addObject("students", students);
        
        modelAndView.addObject("page", page);
        
        modelAndView.addObject("refer", "list");
        modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page"));
        
        modelAndView.addObject("siteId", siteId);
        
        return modelAndView;
    }
    
    /**
     * View student search panel
     * 
     * @param type
     * @return
     */
    @RequestMapping(value = "/{type}-students/search", method = RequestMethod.GET)
    public ModelAndView search(@Secure Login login,
                               @PathVariable("type") String type,
                               @RequestParam(name = "site", required = false) Long site) {
         ModelAndView modelAndView = new ModelAndView("student/student-search");
         
         modelAndView.addObject("type", type);
         modelAndView.addObject("site", login.hasSite() ? login.getSite().getId() : site);
         return modelAndView;
    }
    
    /**
     * 
     * @param studentSearch
     * @param page
     * @param request
     * @return
     */
    @RequestMapping(value = "/online-students", method = RequestMethod.GET, params = "filter")
    @MenuSetting("submenu-online-student-management")
    public ModelAndView onSearch(OnlineStudentSearch studentSearch,
                                 Page page, HttpServletRequest request) {
        
        ModelAndView modelAndView = new ModelAndView("student/student-list");
        
        List<Student> students = studentService.onlineStudentSearch(studentSearch, page);
        modelAndView.addObject("students", students);
        
        modelAndView.addObject("type", "online");
        
        modelAndView.addObject("refer", "search");
        modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page"));
        
        return modelAndView;
    }
    
    @RequestMapping(value = "/offline-students", method = RequestMethod.GET, params = "filter")
    @MenuSetting("submenu-offline-student-management")
    public ModelAndView onSearch(@Secure Login login,
                                 OfflineStudentSearch studentSearch,
                                 Page page, HttpServletRequest request) {
        
        ModelAndView modelAndView = new ModelAndView("student/student-list");
        
        if(studentSearch.getSite() == null && (login.isAreaManager() || login.isAreaServer())) {
            Principal principal = principalService.load(Principal.class, login.getId());
            
            studentSearch.setSites(siteService.listSite(principal));
        }
        
        List<Student> students = studentService.offlineStudentSearch(studentSearch, page);
        modelAndView.addObject("students", students);
        
        modelAndView.addObject("type", "offline");
        
        modelAndView.addObject("refer", "search");
        modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page"));
        
        return modelAndView;
    }
    
    /**
     * Display student view page
     * 
     * @param type
     * @param studentId
     * @return
     */
    @RequestMapping(value = "/{type}-students/{studentId}", method = RequestMethod.GET)
    @MenuSetting("submenu-{type}-student-management")
    public ModelAndView view(@PathVariable("type") String type,
                             @PathVariable("studentId") Long studentId) {
        
        ModelAndView modelAndView = new ModelAndView("student/view/student-view");
        
        Student student = studentService.load(Student.class, studentId);
        modelAndView.addObject("student", student);
        
        boolean isBlackList = smsBlackListService.getBlackList(student.getMobile());
        
        List<CourseRound> courseRounds = courseRoundService.listCourseRound(student, StringUtils.equals(type, "online") ? new CourseType[]{CourseType.ONLINE} : new CourseType[]{CourseType.INDIVIDUAL, CourseType.SPECIAL, CourseType.POSTURE, CourseType.GROUP, CourseType.YEAR});
        modelAndView.addObject("courseRounds", courseRounds);
        
        modelAndView.addObject("type", type);
        
       
        	
        modelAndView.addObject("isBlackList",isBlackList);
       
        
        return modelAndView;
    }
    
    /**
     * 
     * @param type
     * @return
     */
    @RequestMapping(value = "/{type}-students/exist", method = RequestMethod.GET)
    @MenuSetting("submenu-{type}-student-management")
    public ModelAndView exist(@PathVariable("type") String type) {
        ModelAndView modelAndView = new ModelAndView("student/student-mobile");
        
        modelAndView.addObject("type", type);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param login
     * @param mobile
     * @param type
     * @return
     */
    @RequestMapping(value = "/{type}-students/exist", method = RequestMethod.POST)
    public @ResponseBody String onExist(@Secure Login login,
                                        @RequestParam("mobile") String mobile,
                                        @RequestParam("type") String type) {
        
        Result result = new Result();
        
        try {
            
            Student student = null;
            if(login.hasSite() && StringUtils.equals(type, "offline")) {
                student = studentService.load(mobile, login.getSite());
            } else if((login.isAreaManager() || login.isAreaServer()) && StringUtils.equals(type, "offline")) {
                Principal principal = principalService.load(Principal.class, login.getId());
                
                List<Site> sites = siteService.listSite(principal);
                
                student = studentService.load(mobile, sites);
            } else {
                student = studentService.load(type, mobile);
            }
            result.success().data("url", "/" + type + "-students/" + student.getUser().getId() + "/input")
                            .message("用户存在, 等待跳转进入录入页面");
            
        } catch (Exception e) {
            logger.trace("#onExist() - user not exist, mobile is []", mobile);
            result.fail().data("url", "/" + type + "-students")
                         .message("用户不存在");
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    
    /**
     * @param userId
     * @return
     */
    @RequestMapping(value = "/{type}-students/{userId}/input", method = RequestMethod.GET)
    @MenuSetting("submenu-user-management")
    public ModelAndView input(@PathVariable("type") String type, @PathVariable("userId") Long userId) {
        
        ModelAndView modelAndView = new ModelAndView("student/student-input");
        
        modelAndView.addObject("user", userService.load(User.class, userId));
        modelAndView.addObject("type", type);
        
        return modelAndView;
    }
    
    /**
     * @param userId
     * @param user
     * @return
     */
    @RequestMapping(value = "/{type}-students/{userId}/input", method = RequestMethod.PATCH)
    public @ResponseBody String onInput(@PathVariable("userId") Long userId,
                                        @Preloading("id") User user) {

        Result result = new Result();
        
        try {
            
            userService.update(user.editInputTime(new Date()));
            result.success().message("录入档案成功");
            
        } catch (Exception e) {
            logger.error("#onInput() - input user archives fail, exception is [{}]", e);
            result.fail().message("录入档案失败");
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    
    /**
     * Export online students data view.
     * @param login
     * @param type
     * @return
     */
    @RequestMapping(value = "/{type}-students/export-view", method = RequestMethod.GET)
    public ModelAndView export(@Secure Login login, @PathVariable("type") String type, @RequestParam(required = false) Long siteId) {
        
        ModelAndView modelAndView = new ModelAndView("student/student-export");
        
        modelAndView.addObject("type", type);
        
        modelAndView.addObject("siteId", siteId);
                                                
        return modelAndView;
    }
    
    /**
     * Export online students data.
     * @param login
     * @param type
     * @return
     */
    @RequestMapping(value = "/{type}-students/export", method = RequestMethod.GET)
    public ModelAndView onExport(@Secure Login login,
                                 @PathVariable(value = "type") String type,
                                 @RequestParam(name = "siteId", required = false) Long siteId,
                                 @DateTimeFormat(pattern = "yyyy-MM-dd") Date startTime,    
                                 @DateTimeFormat(pattern = "yyyy-MM-dd") Date endTime) {
        
        ModelAndView modelAndView = new ModelAndView(new ExcelTemplateView("student.xls"));
        
        //1.add user information.
        List<Student> userInformations = new ArrayList<Student>();
        
        Site site = null;
        if((login.hasSite() || (siteId != null && siteId != 0)) && StringUtils.equals(type, "offline")) {
            if(login.hasSite()) {
                site = login.getSite();
            }
            else {
                site = siteService.load(siteId);
            }
            userInformations = studentService.exportUserInformation(site, startTime,endTime);
        } else if(StringUtils.equals(type, "offline") && (login.isAreaManager() || login.isAreaServer())) {
            Principal principal = principalService.load(Principal.class, login.getId());
            
            List<Site> sites = siteService.listSite(principal);
            
            userInformations = studentService.exportUserInformation(sites, startTime,endTime);
        } else {
            userInformations = studentService.exportUserInformation(type, startTime,endTime);
        }
        modelAndView.addObject("userInformations", userInformations);
        
        //2.add consuming behaviors.
        List<CourseRound> consumingBehaviors = studentService.exportConsumingBehavior(userInformations);
        modelAndView.addObject("consumingBehaviors",consumingBehaviors);
        
        //3.add course details.
        List<CourseSchedule> courseSchedules = studentService.exportCourseDetail(userInformations);
        modelAndView.addObject("courseSchedules",courseSchedules);

        //4.add freezing course details.
        List<CourseRound> freezingCourseDetails = studentService.exportFreezingCourseDetails(userInformations);
        modelAndView.addObject("freezingCourseDetails", freezingCourseDetails);
        
        //5.add body data.
        List<BodyReport> bodyReports = studentService.exportBodyData(userInformations);
        modelAndView.addObject("bodyReports",bodyReports);

        //add parse dateFormate.
        DateFormat parseFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        modelAndView.addObject("parseFmt",parseFmt);
        
        //add dateFormate.
        DateFormat fmt = new SimpleDateFormat("yyyy年MM月dd日");
        modelAndView.addObject("fmt",fmt);

        return modelAndView;
    }
    
    
}
